package main

import (
	"net/http"
	"html/template"
	"fmt"
	)

// main.go

type UserInfo struct {
	Name   string
	Gender string
	Age    int
}

func sayHello(w http.ResponseWriter, r *http.Request) {

	// 解析指定文件生成模板对象
	//_, err := t.ParseFiles("./hello.tmpl")
	//if err != nil {
	//	fmt.Println("create template failed, err:", err)
	//	return
	//}
	// 自定义一个夸人的模板函数
	kua := func(arg string) (string, error) {
		return arg + "真帅", nil
	}
	t := template.New("hello.tmpl")
	// 采用链式操作在Parse之前调用Funcs添加自定义的kua函数
	t.Funcs(template.FuncMap{"kua": kua})
	_, err := t.ParseFiles("./hello.tmpl")
	if err != nil {
		fmt.Println("create template failed, err:", err)
		return
	}

	// 利用给定数据渲染模板，并将结果写入w
	m1 := map[string]interface{}{
		"name":   "小王子1",
		"gender": "男1",
		"age":    181,
	}
	u1 := UserInfo{
		Name:   "小王子",
		Gender: "男",
		Age:    18,
	}
	hobby := []string{
		"篮球",
		"排球",
	}
	t.Execute(w, map[string]interface{}{
		"u1":u1,
		"m1":m1,
		"hobby":hobby,
		"Name":"女款",
	})
}
// tmplDemo 模板嵌套
func tmplDemo(w http.ResponseWriter, r *http.Request) {
	tmpl, err := template.ParseFiles("./t.tmpl", "./ul.tmpl")
	if err != nil {
		fmt.Println("create template failed, err:", err)
		return
	}
	user := UserInfo{
		Name:   "小王子",
		Gender: "男",
		Age:    18,
	}
	tmpl.Execute(w, user)
}
// index 模板继承
func index(w http.ResponseWriter, r *http.Request){
	tmpl, err := template.ParseGlob("./template/*.tmpl")
	//tmpl, err := template.ParseFiles("./base.tmpl","./index.tmpl")
	//修改默认的标识符
	//template.New("test").Delims("{[", "]}").ParseFiles("./t.tmpl")
	if err != nil {
		fmt.Println("create template failed, err:", err)
		return
	}
	err = tmpl.ExecuteTemplate(w, "index.tmpl", "wjp")
	if err != nil {
		fmt.Println("render template failed, err:", err)
		return
	}
}

func xss(w http.ResponseWriter, r *http.Request){
	tmpl,err := template.New("xss.tmpl").Funcs(template.FuncMap{
		"safe": func(s string)template.HTML {
			return template.HTML(s)
		},
	}).ParseFiles("./xss.tmpl")
	if err != nil {
		fmt.Println("create template failed, err:", err)
		return
	}
	jsStr := `<script>alert('嘿嘿嘿')</script>`
	err = tmpl.Execute(w, jsStr)
	if err != nil {
		fmt.Println(err)
	}
}

func main() {
	http.HandleFunc("/", sayHello)
	http.HandleFunc("/tmpl", tmplDemo)
	http.HandleFunc("/index", index)
	http.HandleFunc("/xss", xss)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		fmt.Println("HTTP server failed,err:", err)
		return
	}
}